import path from 'path';

import { expect } from '@jest/globals';
import fse, { readJsonSync } from 'fs-extra';

import { OptCompression } from '../../../../src/builder/opt-compression-builder.js';
import { RestoolCompressionConfig } from '../../../../src/options/build/build-opt.js';
import { ModuleBuildProfile } from '../../../../src/options/build/module-build-profile.js';
import { ProjectBuildProfile } from '../../../../src/options/build/project-build-profile.js';
import { initExecuteCommand, runHvigorAsync } from '../../common/common';
import { commonJson5Operation } from '../../plugins/common-fun';
import {
  AbilityType,
  APIType,
  APIVersion,
  CaseLevel,
  LanguageType,
  ModuleTemplateType,
  RuntimeOSType,
  SDKType,
} from '../../plugins/project-builder/models/constants';
import { TestCaseBuilder } from '../../plugins/task-builder/task-case-builder';
import { ProjectBuildOption, TestCaseFun } from '../../plugins/task-builder/test-case';
import { TestTaskOptionBuilder } from '../../plugins/task-builder/test-task-option';

const projectBuilderOption: ProjectBuildOption = {
  template: {
    sdk: SDKType.Single,
    runtimeOS: RuntimeOSType.HarmonyOS,
    apiVersion: APIVersion.API11,
    apiType: APIType.STAGE,
    language: LanguageType.ArkTs,
    abilityType: AbilityType.Application,
    entryTemplateType: ModuleTemplateType.EmptyAbility,
  },
};

const testCaseFun: TestCaseFun = async (project, taskConfig, record) => {
  const projectRootPath = project.projectRootPath();

  // 修改工程级 build profile 开启纹理超压缩功能
  await commonJson5Operation(path.resolve(projectRootPath, 'build-profile.json5'), async (jsonContent: ProjectBuildProfile.ProjectProfileOpt) => {
    jsonContent.app.products![0].buildOption = {
      ...jsonContent.app.products![0].buildOption,
      resOptions: generateResOptions('./project-products'),
    };

    jsonContent.app.buildModeSet!.find((buildMode) => buildMode.name === 'debug')!.buildOption = {
      resOptions: generateResOptions('./project-buildModeSet'),
    };
  });

  // 修改模块级 build profile 开启纹理超压缩功能
  await commonJson5Operation(path.resolve(projectRootPath, 'entry', 'build-profile.json5'), async (jsonContent: ModuleBuildProfile.ModuleBuildOpt) => {
    jsonContent.buildOption = {
      resOptions: generateResOptions('./module-buildOption'),
    };

    jsonContent.buildOptionSet!.push({
      name: 'debug',
      resOptions: generateResOptions('./module-buildOptionSet'),
    });

    jsonContent.targets!.find((target) => target.name === 'default')!.config = {
      buildOption: {
        resOptions: generateResOptions('./module-targets'),
      },
    };
  });

  // 修改 hvigorfile.ts 去读取并修改 build profile
  fse.writeFileSync(
    path.resolve(projectRootPath, 'hvigorfile.ts'),
    `
import { appTasks, OhosPluginId } from '@ohos/hvigor-ohos-plugin';
import { hvigor } from '@ohos/hvigor';

hvigor.nodesEvaluated(node => {
    const rootNode = hvigor.getRootNode();
    const appContext = rootNode.getContext(OhosPluginId.OHOS_APP_PLUGIN);
    // 需要确保此处获得的 buildProfileOpt 没有被 build-mode-manager.ts convertCompressionPathToAbsolute() 转换
    const buildProfileOpt = appContext.getBuildProfileOpt(); 
    appContext.setBuildProfileOpt(buildProfileOpt);
});

export default {
    system: appTasks,  /* Built-in plugin of Hvigor. It cannot be modified. */
    plugins:[]         /* Custom plugin to extend the functionality of Hvigor. */
}
  `,
  );

  // build hap
  const buildResult = await runHvigorAsync(
    projectRootPath,
    initExecuteCommand({
      mode: 'module',
      product: 'default',
      module: 'entry@default',
      tasks: 'assembleHap',
    }),
  );
  expect(buildResult.stdout).toContain('BUILD SUCCESSFUL');

  // 检查纹理超压缩的中间产物 opt-compression.json
  const optCompression: OptCompression = readJsonSync(path.resolve(projectRootPath, 'entry/build/default/intermediates/res/default/opt-compression.json'));
  expect(optCompression.compression.filters.length).toBe(5); // 3个模块级filter + 2个工程级filter

  // 工程级 filter 读取到的 png 应该会比模块级的更多，一般是多一个 app-icon.png
  const modulePngCount = optCompression.compression.filters[0].path!.length;
  const projectPngCount = optCompression.compression.filters[3].path!.length;
  expect(projectPngCount > modulePngCount).toBe(true);

  // 模块级filter在前，工程级的在后面
  expect(optCompression.compression.filters[0].path!.length).toBe(modulePngCount);
  expect(optCompression.compression.filters[1].path!.length).toBe(modulePngCount);
  expect(optCompression.compression.filters[2].path!.length).toBe(modulePngCount);
  expect(optCompression.compression.filters[3].path!.length).toBe(projectPngCount);
  expect(optCompression.compression.filters[4].path!.length).toBe(projectPngCount);
};

function generateResOptions(from: string): { compression: RestoolCompressionConfig } {
  return {
    compression: {
      media: {
        enable: true,
      },
      filters: [
        {
          method: {
            type: 'sut',
            blocks: '4x4',
          },
          files: {
            path: ['./**/*.png', from],
          },
        },
      ],
    },
  };
}

TestCaseBuilder.builder()
  .caseName('DTS2024121811424')
  .description('开启图片压缩配置构建报错')
  .projectBuilderOption(projectBuilderOption)
  .taskConfig(TestTaskOptionBuilder.builder().caseLevel(CaseLevel.DTS).build())
  .testFun(testCaseFun)
  .load();
